package com.itliang.web.controller.system;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.itliang.annotation.Log;
import com.itliang.constant.RedisConstants;
import com.itliang.core.model.DeleteRequest;
import com.itliang.core.model.dto.system.sysuser.*;
import com.itliang.core.model.entity.system.SysUser;
import com.itliang.core.model.vo.SysUserVO;
import com.itliang.core.redis.RedisCache;
import com.itliang.core.result.BaseResponse;
import com.itliang.core.result.CodeEnum;
import com.itliang.core.result.ResultUtils;
import com.itliang.enums.BusinessType;
import com.itliang.exception.BusinessException;
import com.itliang.service.system.SysUserService;
import com.itliang.utils.JwtUtils;
import com.itliang.web.service.LoginService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : liangzhuoyuan
 * @createDate : 2023-03-02 18:56
 */
@Api(tags = "用户管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/system/sysUser")
public class SysUserController {

    @Resource
    SysUserService sysUserService;

    @Resource
    private LoginService loginService;

    @Resource
    private RedisCache redisCache;

    // region 登录相关

    @GetMapping("/detail")
    public BaseResponse<?> getUerDetails(HttpServletRequest request) {
        String token = request.getHeader("token");
        Long userId = JwtUtils.getUserId(token);
        SysUser user = sysUserService.getById(userId);
        return ResultUtils.success(user);
    }

    /**
     * 登录
     *
     * @return
     */
    @PostMapping("/login")
    public BaseResponse<Map> login(@RequestBody SysUserLoginRequest sysUserLoginRequest) {
        if (sysUserLoginRequest == null) {
            throw new BusinessException(CodeEnum.PARAMS_ERROR);
        }
        return loginService.login(sysUserLoginRequest);
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    @GetMapping("/info")
    public BaseResponse<Map> info(HttpServletRequest request) {
        String token = request.getHeader("token");
        Long userId = JwtUtils.getUserId(token);
        Map<String, Object> map = sysUserService.getUserInfo(userId);
        return ResultUtils.success(map);
    }

    /**
     * 退出
     *
     * @return
     */
    @PostMapping("/logout")
    public BaseResponse<Map> logout(HttpServletRequest request) {
        String token = request.getHeader("token");
        String account = JwtUtils.getUserAccount(token);
        // 删除redis中的token
        redisCache.deleteObject(RedisConstants.LOGIN_TOKEN_KEY + account);
        // 删除redis中的用户权限列表
        redisCache.deleteObject(RedisConstants.OPERATION_PERMISSION_KEY + account);
        redisCache.deleteObject(RedisConstants.USER_INFO_KEY + account);

        return ResultUtils.success();
    }

    // endregion

    // region 增删改查

    /**
     * 创建用户
     *
     * @param sysUserAddRequest
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public BaseResponse<Long> addUser(@RequestBody SysUserAddRequest sysUserAddRequest) {
        if (sysUserAddRequest == null) {
            throw new BusinessException(CodeEnum.PARAMS_ERROR);
        }
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserAddRequest, sysUser);
        boolean result = sysUserService.save(sysUser);
        if (!result) {
            throw new BusinessException(CodeEnum.OPERATION_ERROR);
        }
        return ResultUtils.success(sysUser.getId());
    }

    /**
     * 删除用户
     *
     * @param deleteRequest
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(CodeEnum.PARAMS_ERROR);
        }
        boolean b = sysUserService.removeById(deleteRequest.getId());
        // TODO 删除用户的同时，要把分配的角色也删除 用户角色表
        return ResultUtils.success(b);
    }

    /**
     * 更新用户
     *
     * @param sysUserUpdateRequest
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/update")
    public BaseResponse<Boolean> updateUser(@RequestBody SysUserUpdateRequest sysUserUpdateRequest) {
        if (sysUserUpdateRequest == null || sysUserUpdateRequest.getId() == null) {
            throw new BusinessException(CodeEnum.PARAMS_ERROR);
        }
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserUpdateRequest, sysUser);
        boolean result = sysUserService.updateById(sysUser);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取用户
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<SysUserVO> getUserById(int id) {
        if (id <= 0) {
            throw new BusinessException(CodeEnum.PARAMS_ERROR);
        }
        SysUser sysUser = sysUserService.getById(id);
        SysUserVO sysUserVO = new SysUserVO();
        BeanUtils.copyProperties(sysUser, sysUserVO);
        return ResultUtils.success(sysUserVO);
    }

    /**
     * 获取用户列表
     *
     * @param sysUserQueryRequest
     * @return
     */
    @GetMapping("/list")
    public BaseResponse<List<SysUserVO>> listUser(SysUserQueryRequest sysUserQueryRequest) {
        SysUser sysUser = new SysUser();
        if (sysUserQueryRequest != null) {
            BeanUtils.copyProperties(sysUserQueryRequest, sysUser);
        }
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>(sysUser);
        List<SysUser> userList = sysUserService.list(queryWrapper);
        List<SysUserVO> userVOList = userList.stream().map(user -> {
            SysUserVO userVO = new SysUserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
        return ResultUtils.success(userVOList);
    }

    /**
     * 分页获取用户列表
     *
     * @param sysUserQueryRequest
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<SysUserVO>> listUserByPage(SysUserQueryRequest sysUserQueryRequest) {
        long current = 1;
        long size = 10;
        SysUser sysUser = new SysUser();
        if (sysUserQueryRequest != null) {
            BeanUtils.copyProperties(sysUserQueryRequest, sysUser);
            current = sysUserQueryRequest.getCurrent();
            size = sysUserQueryRequest.getPageSize();
        }
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>(sysUser);
        Page<SysUser> userPage = sysUserService.page(new Page<>(current, size), queryWrapper);
        Page<SysUserVO> userVOPage = new PageDTO<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        List<SysUserVO> userVOList = userPage.getRecords().stream().map(user -> {
            SysUserVO userVO = new SysUserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
        userVOPage.setRecords(userVOList);
        return ResultUtils.success(userVOPage);
    }

    // endregion

    /**
     * 更新用户状态
     *
     * @param updateStatusRequest
     * @return
     */
    @Log(title = "用户管理", businessType = BusinessType.STATUS)
    @GetMapping("/update/status")
    public BaseResponse<Boolean> updateStatus(SysUserUpdateStatusRequest updateStatusRequest) {
        if (updateStatusRequest == null || updateStatusRequest.getId() == null) {
            throw new BusinessException(CodeEnum.PARAMS_ERROR);
        }
        if (updateStatusRequest.getStatus() != 0 && updateStatusRequest.getStatus() != 1) {
            throw new BusinessException(CodeEnum.PARAMS_ERROR);
        }
        boolean result = sysUserService.updateStatus(updateStatusRequest);
        return ResultUtils.success(result);
    }
}
